/* json.h : dgnsc json parser
 * Copyright (C) 2009-2011 drangon <drangon.zhou@gmail.com>
 * 2011-09
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef INCLUDED_DGNSC_JSON_H
#define INCLUDED_DGNSC_JSON_H

#include <dgnsc/str.h>
#include <dgnsc/hashkv.h>

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

typedef struct dgn_json_st * dgn_json_t;
typedef dgn_hashkv_iter_t dgn_json_iter_t;

enum dgn_json_type_e {
	DGN_JSON_UNKNOWN = 0,
	DGN_JSON_NULL,
	DGN_JSON_TRUE,
	DGN_JSON_FALSE,
	DGN_JSON_INT,
	DGN_JSON_DOUBLE,
	DGN_JSON_STRING,
	DGN_JSON_ARRAY,
	DGN_JSON_OBJECT,
};

// create
dgn_json_t dgn_json_init( enum dgn_json_type_e type );
dgn_json_t dgn_json_init_int( int val );
dgn_json_t dgn_json_init_double( double val );
dgn_json_t dgn_json_init_string( const char * str, int len );
dgn_json_t dgn_json_init_dup( dgn_json_t js );
// parser, str must end with '\0'
dgn_json_t dgn_json_init_parse( const char * str, int * used_len );
void dgn_json_fini( dgn_json_t js );

// get value
enum dgn_json_type_e dgn_json_get_type( dgn_json_t js );
int dgn_json_get_int( dgn_json_t js ); // return 0 if wrong type
double dgn_json_get_double( dgn_json_t js );  // return 0.0 if wrong type
const char * dgn_json_get_string( dgn_json_t js ); // return NULL if wrong type
int dgn_json_get_array_num( dgn_json_t js );
dgn_json_t dgn_json_get_array( dgn_json_t js, int index ); // return NULL if wrong type
int dgn_json_get_object_num( dgn_json_t js );
dgn_json_t dgn_json_get_object( dgn_json_t js, const char * key ); // return NULL if wrong type

// set value, automatic change type
void dgn_json_set_type( dgn_json_t js, enum dgn_json_type_e type );
void dgn_json_set_int( dgn_json_t js, int val );
void dgn_json_set_double( dgn_json_t js, double val );
void dgn_json_set_string( dgn_json_t js, const char * str, int len );

// sub node must not belong to other, will own and release by js
// if index invalid, do nothing, return < 0, not auto change type
int dgn_json_set_array( dgn_json_t js, int index, dgn_json_t node ); 
int dgn_json_set_array_ex( dgn_json_t js, int index, dgn_json_t node, dgn_json_t * old_node ); 
// if before_index < 0 or >= num, then insert at back, auto change type
int dgn_json_insert_array( dgn_json_t js, int before_index, dgn_json_t node );
// if ret_node == NULL, then not return node but release it
int dgn_json_del_array( dgn_json_t js, int index, dgn_json_t * ret_node );

// str will be copy, but node will own and release by js
int dgn_json_set_object( dgn_json_t js, const char * str, dgn_json_t node );
int dgn_json_set_object_ex( dgn_json_t js, const char * str, int len, dgn_json_t node, dgn_json_t * old_node );
int dgn_json_del_object( dgn_json_t js, const char * str, dgn_json_t * ret_value );

// iterator, object only
dgn_json_iter_t dgn_json_iter_next( dgn_json_t js, dgn_json_iter_t prev );
dgn_json_iter_t dgn_json_iter_find( dgn_json_t js, const char * key );
const char * dgn_json_iter_get_key( dgn_json_t js, dgn_json_iter_t iter );
dgn_json_t dgn_json_iter_get( dgn_json_t js, dgn_json_iter_t iter );
int dgn_json_iter_set( dgn_json_t js, dgn_json_iter_t iter, dgn_json_t value, dgn_json_t * old_value );
dgn_json_iter_t dgn_json_iter_del( dgn_json_t js, dgn_json_iter_t iter, dgn_json_t * old_value );

int dgn_json_output( dgn_json_t js, dgn_str_t buf );

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // INCLUDED_DGNSC_JSON_H

